package cn.zyjblogs.config.security;

import cn.zyjblogs.starter.common.autoconfigure.rsa.RsaKeyProperties;
import cn.zyjblogs.starter.common.entity.constant.CommonRedisKeyConstant;
import cn.zyjblogs.starter.common.entity.response.HttpCode;
import cn.zyjblogs.starter.common.exception.AuthRuntimeException;
import cn.zyjblogs.starter.redis.utils.RedisTemplateHandler;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;

/**
 * @author zhuyijun
 */
@Configuration
@RequiredArgsConstructor
public class JwtTokenConfig {
    private final OauthUserAuthenticationConverter oauthUserAuthenticationConverter;
    private final RsaKeyProperties rsaKeyProperties;
    private final RedisTemplateHandler<String, String> redisTemplateHandler;

    /**
     * 令牌存储策略
     *
     * @return
     */
    @Bean
    public TokenStore tokenStore() {
        //JWT令牌存储方案
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        try {
            if (Boolean.TRUE.equals(rsaKeyProperties.getEnable())) {
                String publicKey = IOUtils.toString(Paths.get(rsaKeyProperties.getPubKeyPath()).toUri(), StandardCharsets.UTF_8);
                String privateKey = IOUtils.toString(Paths.get(rsaKeyProperties.getPriKeyPath()).toUri(), StandardCharsets.UTF_8);
                // 私钥签名
                converter.setSigningKey(privateKey);
                // 公钥验签
                converter.setVerifierKey(publicKey);
                redisTemplateHandler.set(CommonRedisKeyConstant.REDIS_KEY_PRIVATE_RSA, privateKey);
                redisTemplateHandler.set(CommonRedisKeyConstant.REDIS_KEY_PUBLIC_RSA, publicKey);
            }
        } catch (final IOException e) {
            throw new AuthRuntimeException(HttpCode.INTERNAL_SERVER_ERROR, "获取不到公私密钥");
        }
        OauthAccessTokenConverter accessTokenConverter = new OauthAccessTokenConverter();
        accessTokenConverter.setUserTokenConverter(oauthUserAuthenticationConverter);
        converter.setAccessTokenConverter(accessTokenConverter);
        return converter;
    }
}
